package cases

import (
	"encoding/json"
	"fmt"
	"github.com/beego/beego/v2/core/validation"
	"github.com/beego/beego/v2/server/web/pagination"
	"log"
	"strconv"
	"strings"
	"time"
	"xpms/controllers"
	"xpms/cores"
	"xpms/cores/utils"
)

// 用例包管理
type CasePkgController struct {
	controllers.BaseController
}

// @Title 分页查询项目用例包管理数据
// @Description 分页查询项目用例包管理数据
// @Param	id		path 	string	true		"项目id"
// @Param	pkgid		query 	string			"用例包id"
// @Param	acceptid		query 	[]string			"负责人"
// @Param	p		query 	int	true		"第几页"
// @Param	pageoffset		query 	int			"每页数"
// @Param	keyword		query 	string			"关键字"
// @Success 200 {object} cases.TestCasePkg   int   int  int
// @Failure 403 case not exist
// @router /:id/page [get]
func (u *CasePkgController) Page() {
	page, err := u.GetInt("p")
	if err != nil {
		page = 1
	}
	offset, err := u.GetInt("pageoffset")
	if err != nil {
		offset = 15
	}
	id, err := u.GetInt64(":id")
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "未选择对应的项目" + err.Error()}
		u.ServeJSON()
		return
	}
	keyword := u.GetString("keyword")
	pkgid := u.GetString("pkgid")
	acceptid := u.GetStrings("acceptid")
	condArr := make(map[string]interface{})
	condArr["projectid"] = id
	condArr["keyword"] = keyword
	condArr["id"] = pkgid
	condArr["acceptid"] = acceptid
	countUser := CasePkgPageCountExec(condArr, page, offset)
	paginator := pagination.SetPaginator(u.Ctx, offset, countUser)
	modeData := CasePkgPageExec(condArr, page, offset)
	type data struct {
		Modules  []TestCasePkg
		Total    int64
		PageNums int
		Page     int
	}
	d := &data{modeData, paginator.Nums(), paginator.PageNums(), paginator.Page()}
	var responseEntity cores.ResponseEntity
	u.Data["json"] = responseEntity.Build(d).Data
	u.Ctx.Output.Status = responseEntity.StatusCode
	u.ServeJSON()
}

// @Title Create 用例包
// @Description create 用例包
// @Param	body		body 	cases.TestCasePkg	true		"body for case content"
// @Success 200 {string} string
// @Failure 403 body is empty
// @router / [post]
func (u *CasePkgController) Create() {
	var f TestCasePkg
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(f.Name, "name").Message("包名称不能为空")
	valid.Required(f.Projectid, "Projectid").Message("项目不能为空")
	b, err := valid.Valid(&f)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	exists, err1 := GetCasePkgByname(f.Name)
	if err1 != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "查询数据异常"}
		u.ServeJSON()
		return
	} else if !utils.IsEmpty(f.Id) && exists.Id != f.Id {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "测试包重复"}
		u.ServeJSON()
		return
	} else if !utils.IsEmpty(exists.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "测试包重复"}
		u.ServeJSON()
		return
	}
	userid := u.BaseController.UserUserId
	id := utils.SnowFlakeId()
	f.Id = id
	f.Changid = userid
	f.Createid = userid
	err = AddCasePkg(f)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息添加成功", "id": fmt.Sprintf("%d", id)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息添加失败"}
	}
	u.ServeJSON()
}

// @Title update 用例包
// @Description update 用例包
// @Param	body		body 	cases.TestCasePkg	true		"body for case content"
// @Success 200 {string} string
// @Failure 403 body is empty
// @router / [put]
func (u *CasePkgController) Upadate() {
	var f TestCasePkg
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(f.Id, "name").Message("用例包id不能为空")
	b, err := valid.Valid(&f)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	exists, err1 := GetCasePkgByname(f.Name)
	if err1 != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "查询数据异常"}
		u.ServeJSON()
		return
	} else if !utils.IsEmpty(f.Id) && exists.Id != f.Id {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "测试包重复"}
		u.ServeJSON()
		return
	} else if !utils.IsEmpty(exists.Id) {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "测试包重复"}
		u.ServeJSON()
		return
	}
	userid := u.BaseController.UserUserId
	f.Changid = userid
	f.Changed = time.Now().Unix()
	err = UpdateCasePkg(f)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息添加成功", "id": fmt.Sprintf("%d", f.Id)}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息添加失败"}
	}
	u.ServeJSON()
}

// @Title Get
// @Description get case by id
// @Param	id		path 	string	true		"The key for case"
// @Success 200 {object} cases.TestCasePkg
// @Failure 403 :id is empty
// @router /:id [get]
func (u *CasePkgController) Get() {
	uid := u.GetString(":id")
	if uid != "" {
		int64, err := strconv.ParseInt(uid, 10, 64)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "测试包id为空"}
			return
		}
		modeData, err := GetCasePkgById(int64)
		if err != nil {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息修改失败"}
		} else {
			u.Data["json"] = modeData
		}
	}
	u.ServeJSON()
}

/**
  添加测试包中测试case
*/
type AddCasePkgCaseDto struct {
	Pkgid  int64 `json:"Pkgid,string"`
	Caseid []string
}

// @Title Create 用例包中添加测试用例
// @Description Create 用例包中添加测试用例
// @Param	body		body 	cases.AddCasePkgCaseDto	true		"body for AddCasePkgCaseDto content"
// @Success 200 {string} string
// @Failure 403 body is empty
// @router /case [post]
func (u *CasePkgController) CreatePkgCase() {
	var f AddCasePkgCaseDto
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(f.Pkgid, "Pkgid").Message("用例包id不能为空")
	valid.Required(f.Caseid, "Caseid").Message("用例id不能为空")
	b, err := valid.Valid(&f)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	err = AddPkgCases(u.UserUserId, f)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息添加成功"}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息添加失败"}
	}
	u.ServeJSON()
}

/**
  添加测试包中测试case
*/
type DelCasePkgCaseDto struct {
	ids []int64 `json:"ids,string"`
}

// @Title del 用例包中添加测试用例
// @Description del 用例包中添加测试用例
// @Param	body		body 	cases.DelCasePkgCaseDto	true		"body for DelCasePkgCaseDto content"
// @Success 200 {string} string
// @Failure 403 body is empty
// @router /case [delete]
func (u *CasePkgController) DelPkgCase() {
	var f DelCasePkgCaseDto
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &f)
	// 开始校验输入值
	valid := validation.Validation{}
	valid.Required(f.ids, "ids").Message("id不能为空")
	b, err := valid.Valid(&f)
	if err != nil {
		// handle error
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "严重异常" + err.Error()}
		u.ServeJSON()
		return
	}
	if !b {
		var validMsg []string
		// validation does not pass
		for _, err := range valid.Errors {
			validMsg = append(validMsg, err.Message)
			log.Println(err.Key, err.Message)
		}
		if !utils.IsEmpty(validMsg) {
			u.Data["json"] = map[string]interface{}{"code": 0, "message": strings.Join(validMsg, ",")}
			u.ServeJSON()
			return
		}
	}
	err = DelPkgCases(f.ids)
	if err == nil {
		u.Data["json"] = map[string]interface{}{"code": 1, "message": "信息添加成功"}
	} else {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "信息添加失败"}
	}
	u.ServeJSON()
}

// @Title 分页查询项目用例包管理数据
// @Description 分页查询项目用例包管理数据
// @Param	id		path 	string	true		"项目id"
// @Param	pkgid		query 	string			"用例包id"
// @Param	p		query 	int	true		"第几页"
// @Param	pageoffset		query 	int			"每页数"
// @Param	keyword		query 	string			"关键字"
// @Success 200 {object} cases.TestCasePkg   int   int  int
// @Failure 403 case not exist
// @router /case/:id/page [get]
func (u *CasePkgController) PkgCasePage() {
	page, err := u.GetInt("p")
	if err != nil {
		page = 1
	}
	offset, err := u.GetInt("pageoffset")
	if err != nil {
		offset = 15
	}
	_, err = u.GetInt64(":id")
	if err != nil {
		u.Data["json"] = map[string]interface{}{"code": 0, "message": "未选择对应的项目" + err.Error()}
		u.ServeJSON()
		return
	}
	keyword := u.GetString("keyword")
	pkgid := u.GetString("pkgid")
	caseid := u.GetString("caseid")
	kid := u.GetString("kid")
	condArr := make(map[string]interface{})
	condArr["id"] = kid
	condArr["caseid"] = caseid
	condArr["keyword"] = keyword
	condArr["pkgid"] = pkgid
	countUser := PkgCasePageCountExec(condArr, page, offset)
	paginator := pagination.SetPaginator(u.Ctx, offset, countUser)
	modeData := PkgCasePageExec(condArr, page, offset)
	type data struct {
		Modules  []TestCasePkgCase
		Total    int64
		PageNums int
		Page     int
	}
	d := &data{modeData, paginator.Nums(), paginator.PageNums(), paginator.Page()}
	var responseEntity cores.ResponseEntity
	u.Data["json"] = responseEntity.Build(d).Data
	u.Ctx.Output.Status = responseEntity.StatusCode
	u.ServeJSON()
}
